import config,logging
from models import GroupCommand

class CommandNotValid(Exception):
    def __init__(self,value):
        self.value=value
    def __str__(self):
        return repr(self.value)

class NotACommand(Exception):
    def __init__(self,value):
        self.value=value
    def __str__(self):
        return repr(self.value)

class CommandProcessError(Exception):
    def __init__(self,value):
        self.value=value
    def __str__(self):
        return repr(self.value)

class CommandProcessor:
    def __init__(self,msg_processor):
        self.sender=msg_processor.sender
        self.cmd_body=msg_processor.body
        
    def process(self,command=None):
        if not command is None:
            cmd=command
        else:
            cmd=self.cmd_body

        (isvalid,prefix,identifier,parameters)=self.validate(cmd)
        if not isvalid:
            raise NotACommand
        
        command_list=memcache.get('command_list')
        if command_list is None:
            entities=GroupCommand.all()
            command_list={}
            for entity in entities:
                module=__import__('plugins.%s'% str.lower(entity.identifier))
                command_list[entity.identifier]={
                                                 'prefix' : entity.prefix,
                                                 'handler': module.__dict__['main']
                                                 }
            # try to cache command_list,maybe encounter errors if the cached size is
            # over 1MB
            try:
                memcache.set('command_list',command_list)
            except ValueError as e:
                logging.error("memcache.set error: %s" % e)
                raise CommandProcessError("Memcache Error Occured!")
        
        if not command_list.has_key(identifier):
            logging.info("CommandProcessor: %s is not a available command identifier.")
            raise CommandNotValid
        
        command_list[identifier]['handler'](parameters)
                
    
    def validate(self,msg_body):
        parts=str.split(msg_body)
        for prefix in config.command['prefix']:
            if parts[0].startswith(prefix):
                _,_,identifier=str.partition(parts[0],prefix)
                parameters=parts[1:]
                return True,prefix,identifier,parameters
